package com.itmake.sample.itext.utils;

import com.itmake.sample.itext.model.po.WaterText;
import com.itmake.sample.itext.model.po.WaterImage;
import com.itmake.sample.toolbox.file.NetFileUtil;
import org.springframework.util.CollectionUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import org.springframework.stereotype.Component;

/**
 * 图片水印工具类
 *
 * @author Amjacks
 * @since 2023/08/10
 */
@Component
public class WaterMarkUtil {

    /**
     * 制作水印
     *
     * @param os             输出流
     * @param imgUrl         地图路径
     * @param waterImageList 图片水印列表
     * @param waterTextList  文字水印列表
     */
    public void markWaterMark(String imgUrl,
                              List<WaterImage> waterImageList,
                              List<WaterText> waterTextList,
                              String typeName,
                              OutputStream os) throws IOException {
        markWaterMark(NetFileUtil.getNetFile(imgUrl), waterImageList, waterTextList, typeName, os);
    }

    /**
     * 制作水印
     *
     * @param os             输出流
     * @param imgIn          底图的输入流
     * @param waterImageList 图片水印列表
     * @param waterTextList  文字水印列表
     */
    public void markWaterMark(BufferedInputStream imgIn,
                              List<WaterImage> waterImageList,
                              List<WaterText> waterTextList,
                              String typeName,
                              OutputStream os) throws IOException {
        markWaterMark(ImageIO.read(imgIn), waterImageList, waterTextList, typeName, os);
    }

    /**
     * 制作水印
     *
     * @param os             输出流
     * @param srcImg         底图对象
     * @param waterImageList 图片水印列表
     * @param waterTextList  文字水印列表
     */
    public void markWaterMark(BufferedImage srcImg,
                              List<WaterImage> waterImageList,
                              List<WaterText> waterTextList,
                              String typeName,
                              OutputStream os) throws IOException {

        BufferedImage bufferedImage = markWaterMark(srcImg, waterImageList, waterTextList);
        // 1、生成图片
        ImageIO.write(bufferedImage, typeName.toLowerCase(), os);
        // 2、释放资源
        bufferedImage.flush();
        os.flush();
        os.close();
    }

    /**
     * 制作水印
     *
     * @param srcImg         底图对象
     * @param waterImageList 图片水印列表
     * @param waterTextList  文字水印列表
     */
    public BufferedImage markWaterMark(BufferedImage srcImg,
                                       List<WaterImage> waterImageList,
                                       List<WaterText> waterTextList) throws IOException {
        // 1、初始化画布
        int imgWidth = srcImg.getWidth(null);
        int imgHeight = srcImg.getHeight(null);
        // 图片流
        BufferedImage canvas = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
        // 2、得到画笔对象
        Graphics2D g = canvas.createGraphics();
        // 3、设置对线段的锯齿状边缘处理
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, null);
        // 4、设置图片水印
        if (!CollectionUtils.isEmpty(waterImageList)) {
            setImageMark(g, waterImageList);
        }
        // 5、设置文字水印
        if (!CollectionUtils.isEmpty(waterTextList)) {
            setTextMark(g, waterTextList);
        }
        // 6、释放资源
        g.dispose();
        srcImg.flush();
        // 7、返回图片
        return canvas;
    }

    /**
     * 设置图片水印
     *
     * @param graphics2D     画笔对象
     * @param waterImageList 图片水印列表
     * @throws IOException ioexception
     */
    private void setImageMark(Graphics2D graphics2D, List<WaterImage> waterImageList) throws IOException {
        BufferedImage logoImg = null;
        for (WaterImage waterImage : waterImageList) {
            // 1、设置旋转
            graphics2D.rotate(Math.toRadians(waterImage.getDegree()));
            // 2、设置透明度
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, waterImage.getAlpha()));
            // 3、读取图片
            BufferedInputStream netFile = NetFileUtil.getNetFile(waterImage.getUrlPath());
            logoImg = ImageIO.read(netFile);
            // 4、画图
            graphics2D.drawImage(logoImg, waterImage.getOffsetX(), waterImage.getOffsetY(), waterImage.getWidth(), waterImage.getHeight(), null);
            // 5、旋转归位
            graphics2D.rotate(-Math.toRadians(waterImage.getDegree()));
            // 6、释放资源
            logoImg.flush();
        }
    }

    /**
     * 设置文字水印
     *
     * @param graphics2D     画笔对象
     * @param waterTextList 文字水印列表
     * @throws IOException ioexception
     */
    private void setTextMark(Graphics2D graphics2D, List<WaterText> waterTextList) {
        for (WaterText waterText : waterTextList) {
            // 1、设置旋转
            graphics2D.rotate(Math.toRadians(waterText.getDegree()));
            // 2、设置水印文字颜色
            /*Color color = Color.getColor(waterText.getColor());
            if (Objects.isNull(color)) {
                throw new BaseException("文字" + waterText.getText() + "所设置的颜色不存在");
            }*/
            graphics2D.setColor(Color.ORANGE);
            // 3、设置水印文字Font
            /*Font font = Font.getFont(waterText.getFont());
            if (Objects.isNull(font)) {
                throw new BaseException("文字" + waterText.getText() + "所设置的字体不存在");
            }*/
            graphics2D.setFont(new Font("宋体", Font.BOLD, 30));
            // 4、设置水印文字透明度
            graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, waterText.getAlpha()));
            // 5、画图
            graphics2D.drawString(waterText.getText(), waterText.getOffsetX(), waterText.getOffsetY());
            // 6、旋转归位
            graphics2D.rotate(-Math.toRadians(waterText.getDegree()));
        }
    }
}
